import { Request, Response, NextFunction } from 'express';
import { body, param, query, validationResult } from 'express-validator';
import { createValidationError } from './error';

// 验证结果检查中间件
export const checkValidationResult = (req: Request, res: Response, next: NextFunction): void => {
  const errors = validationResult(req);
  
  if (!errors.isEmpty()) {
    const errorMessages = errors.array().map(error => ({
      field: error.type === 'field' ? (error as any).path : 'unknown',
      message: error.msg,
      value: error.type === 'field' ? (error as any).value : undefined,
    }));

    res.status(400).json({
      success: false,
      message: 'Validation failed',
      code: 'VALIDATION_ERROR',
      errors: errorMessages,
    });
    return;
  }
  
  next();
};

// 用户注册验证
export const validateUserRegistration = [
  body('email')
    .isEmail()
    .withMessage('Please provide a valid email address')
    .normalizeEmail(),
  body('username')
    .isLength({ min: 1, max: 30 })
    .withMessage('Username must be between 1 and 30 characters')
    .matches(/^[a-zA-Z0-9_]+$/)
    .withMessage('Username can only contain letters, numbers, and underscores'),
  body('password')
    .isLength({ min: 8 })
    .withMessage('Password must be at least 8 characters long')
    .matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/)
    .withMessage('Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character'),
  body('nickname')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('Nickname must be between 1 and 50 characters'),
  checkValidationResult,
];

// 用户登录验证
export const validateUserLogin = [
  body('email')
    .isEmail()
    .withMessage('Please provide a valid email address')
    .normalizeEmail(),
  body('password')
    .notEmpty()
    .withMessage('Password is required'),
  checkValidationResult,
];

// 用户资料更新验证
export const validateUserProfileUpdate = [
  body('nickname')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('Nickname must be between 1 and 50 characters'),
  body('bio')
    .optional()
    .isLength({ max: 500 })
    .withMessage('Bio must not exceed 500 characters'),
  body('birthday')
    .optional()
    .isISO8601()
    .withMessage('Birthday must be a valid date'),
  body('gender')
    .optional()
    .isIn(['male', 'female', 'other'])
    .withMessage('Gender must be male, female, or other'),
  checkValidationResult,
];

// 密码更改验证
export const validatePasswordChange = [
  body('currentPassword')
    .notEmpty()
    .withMessage('Current password is required'),
  body('newPassword')
    .isLength({ min: 8 })
    .withMessage('New password must be at least 8 characters long')
    .matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/)
    .withMessage('New password must contain at least one uppercase letter, one lowercase letter, one number, and one special character'),
  body('confirmPassword')
    .custom((value, { req }) => {
      if (value !== req.body.newPassword) {
        throw new Error('Password confirmation does not match new password');
      }
      return true;
    }),
  checkValidationResult,
];

// 伙伴邀请验证
export const validatePartnerInvite = [
  body('inviteCode')
    .isLength({ min: 6, max: 10 })
    .withMessage('Invite code must be between 6 and 10 characters')
    .matches(/^[A-Z0-9]+$/)
    .withMessage('Invite code can only contain uppercase letters and numbers'),
  checkValidationResult,
];

// 消息发送验证
export const validateMessageSend = [
  body('content')
    .notEmpty()
    .withMessage('Message content is required')
    .isLength({ max: 2000 })
    .withMessage('Message content must not exceed 2000 characters'),
  body('type')
    .optional()
    .isIn(['text', 'image', 'file', 'emoji'])
    .withMessage('Message type must be text, image, file, or emoji'),
  body('receiverId')
    .notEmpty()
    .withMessage('Receiver ID is required')
    .isString()
    .withMessage('Receiver ID must be a string'),
  checkValidationResult,
];

// 计划创建验证
export const validatePlanCreation = [
  body('title')
    .notEmpty()
    .withMessage('Plan title is required')
    .isLength({ min: 1, max: 200 })
    .withMessage('Plan title must be between 1 and 200 characters'),
  body('description')
    .optional()
    .isLength({ max: 1000 })
    .withMessage('Plan description must not exceed 1000 characters'),
  body('category')
    .optional()
    .isIn(['travel', 'date', 'goal', 'general'])
    .withMessage('Plan category must be travel, date, goal, or general'),
  body('priority')
    .optional()
    .isIn(['low', 'medium', 'high'])
    .withMessage('Plan priority must be low, medium, or high'),
  body('startDate')
    .optional()
    .isISO8601()
    .withMessage('Start date must be a valid date'),
  body('endDate')
    .optional()
    .isISO8601()
    .withMessage('End date must be a valid date')
    .custom((value, { req }) => {
      if (value && req.body.startDate && new Date(value) <= new Date(req.body.startDate)) {
        throw new Error('End date must be after start date');
      }
      return true;
    }),
  checkValidationResult,
];

// 任务创建验证
export const validateTaskCreation = [
  body('title')
    .notEmpty()
    .withMessage('Task title is required')
    .isLength({ min: 1, max: 200 })
    .withMessage('Task title must be between 1 and 200 characters'),
  body('description')
    .optional()
    .isLength({ max: 1000 })
    .withMessage('Task description must not exceed 1000 characters'),
  body('priority')
    .optional()
    .isIn(['low', 'medium', 'high'])
    .withMessage('Task priority must be low, medium, or high'),
  body('dueDate')
    .optional()
    .isISO8601()
    .withMessage('Due date must be a valid date'),
  body('planId')
    .notEmpty()
    .withMessage('Plan ID is required')
    .isString()
    .withMessage('Plan ID must be a string'),
  checkValidationResult,
];

// 相册创建验证
export const validateAlbumCreation = [
  body('title')
    .notEmpty()
    .withMessage('Album title is required')
    .isLength({ min: 1, max: 100 })
    .withMessage('Album title must be between 1 and 100 characters'),
  body('description')
    .optional()
    .isLength({ max: 500 })
    .withMessage('Album description must not exceed 500 characters'),
  checkValidationResult,
];

// 照片上传验证
export const validatePhotoUpload = [
  body('description')
    .optional()
    .isLength({ max: 500 })
    .withMessage('Photo description must not exceed 500 characters'),
  body('tags')
    .optional()
    .isArray()
    .withMessage('Tags must be an array'),
  body('tags.*')
    .optional()
    .isString()
    .withMessage('Each tag must be a string')
    .isLength({ min: 1, max: 50 })
    .withMessage('Each tag must be between 1 and 50 characters'),
  body('albumId')
    .notEmpty()
    .withMessage('Album ID is required')
    .isString()
    .withMessage('Album ID must be a string'),
  checkValidationResult,
];

// ID参数验证
export const validateIdParam = [
  param('id')
    .notEmpty()
    .withMessage('ID parameter is required')
    .isString()
    .withMessage('ID must be a string'),
  checkValidationResult,
];

// 分页查询验证
export const validatePagination = [
  query('page')
    .optional()
    .isInt({ min: 1 })
    .withMessage('Page must be a positive integer'),
  query('limit')
    .optional()
    .isInt({ min: 1, max: 100 })
    .withMessage('Limit must be between 1 and 100'),
  checkValidationResult,
];